/**
 * @Date: Mar 8, 2010 8:07:06 PM
 */
package com.philip.journal.home.controller.action;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;

import com.philip.journal.core.Constant;
import com.philip.journal.core.controller.JsonResponseHandler;
import com.philip.journal.core.controller.ResponseHandler;
import com.philip.journal.core.exception.JournalException;
import com.philip.journal.core.service.ServiceProxy;
import com.philip.journal.home.bean.Branch;
import com.philip.journal.home.bean.Entry;
import com.philip.journal.home.service.util.BeanToMapConverter;

/**
 * This action will handle requests for getting the List/Children of a given Branch ID.
 *
 * @author cry30
 */
public class BranchChildrenAction extends AbstractTreeAction {

    /** Reference to form node. Can either be Branch or Entry. */
    private transient String node;

    /**
     * Default delegate constructor.
     *
     * @param serviceProxy Service proxy to be injected by Spring.
     * @param responseHandler Response handler to be injected by Spring.
     */
    public BranchChildrenAction(final ServiceProxy serviceProxy, final ResponseHandler responseHandler) {
        super(serviceProxy, responseHandler);
    }

    @Override
    public void execute() throws ServletException, IOException {
        final long branchId = parseId(node);
        try {
            final List<Branch> children = getServiceProxy().getChildren(branchId);
            final List<Entry> entries = getServiceProxy().getEntries(branchId);

            final BeanToMapConverter branchConverter = getResponseHandler().getConverterFactoryMap().get(
                    Constant.BeanConverter.BRANCH_TO_JSON);
            final BeanToMapConverter entryConverter = getResponseHandler().getConverterFactoryMap().get(
                    Constant.BeanConverter.ENTRY_TO_JSONNODE);

            final List<Map<String, Object>> convertedBranches = branchConverter.convert(children);
            final List<Map<String, Object>> convertedEntries = entryConverter.convert(entries);

            final List<Map<String, Object>> converted = new ArrayList<Map<String, Object>>();
            converted.addAll(convertedBranches);
            converted.addAll(convertedEntries);
            patchId(converted);
            getResponseHandler().respondList(getHttpServletResponse(), converted, null);
        } catch (final JournalException e) {
            getLogger().debug(e.getMessage(), e);
            getResponseHandler().respondFail(getHttpServletResponse(), e.getMessage());
        }
    }

    /**
     * This method will prefix the id to avoid conflict since branch and leaf may intersect each other.
     *
     * @param list List of JSON objects.
     */
    private void patchId(final List<Map<String, Object>> list) {
        for (final Map<String, Object> map : list) {
            final boolean isLeaf = ((Boolean) map.get(JsonResponseHandler.ISLEAF)).booleanValue();
            final String jsonId = map.get(JsonResponseHandler.JSON_ID).toString();
            map.put(JsonResponseHandler.JSON_ID, (isLeaf ? "l-" : "b-") + jsonId);
        }
    }

    /**
     * Setter for node form field.
     *
     * @param pNode form node attribute to set.
     */
    public void setNode(final String pNode) {
        this.node = pNode;
    }
}
